#include "NTgames.h"

void (*NTThread::p)();

string IntToString(int poker)
{
	std::stringstream ss;
	ss << poker;
	std::string str = ss.str();
	return str;
}

CCSprite* getBlackBackground(uint8_t alpha)
{
	CCSprite* t = ResourceManager::getInstance()->createWithSpriteFrameName(IntToString(alpha)+".png");
	if (t)
		return t;
	return ResourceManager::getInstance()->createWithSpriteFrameName("black.png");
}

NTGamePlayType NTLayer::GamePlayType;

ResourceManager* ResourceManager::instance = NULL;
ResourceManager* ResourceManager::getInstance()
{
	if (instance == NULL)
	{
		instance = new ResourceManager();
		instance->readObjBoundaryFile();
	}
	return instance;
}

SoundManager* SoundManager::instance = NULL;
SoundManager* SoundManager::getInstance()
{
	if (instance == NULL)
	{
		instance = new SoundManager();
	}
	return instance;
}

StringManager* StringManager::instance = NULL;
StringManager* StringManager::GetInstance()
{
	if (instance == NULL)
	{
		instance = new StringManager();
	}
	return instance;
}

NetworkManager* NetworkManager::instance = NULL;
NetworkManager* NetworkManager::getInstance()
{
	if (instance == NULL)
	{
		instance = new NetworkManager();
	}
	return instance;
}


const ObjBoundary* ResourceManager::getObjBoundaryByImageName(string strName)
{
	// check if not exist -> null
	if(instance->m_mapObjBoundary.count(strName) > 0)
	{
		return &(instance->m_mapObjBoundary[strName]);
	}
	return NULL;
}

ObjBoundaryItem ResourceManager::getBoundaryItem(string strName, tinyxml2::XMLElement* pElement)
{
	ObjBoundaryItem objItem;
	objItem.setVisible(atoi(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_VISIBLE)->GetText()));
	if(objItem.getVisible())
	{
		objItem.setTopLeft(ccp(	(float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_TOP_LEFT)->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText()), 
								(float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_TOP_LEFT)->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText())));
		objItem.setTopRight(ccp((float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_TOP_RIGHT)->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText()), 
								(float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_TOP_RIGHT)->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText())));
		objItem.setMidLeft(ccp(	(float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_MID_LEFT)->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText()), 
								(float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_MID_LEFT)->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText())));
		objItem.setMidRight(ccp((float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_MID_RIGHT)->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText()), 
								(float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_MID_RIGHT)->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText())));
		objItem.setBotLeft(ccp(	(float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_BOT_LEFT)->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText()), 
								(float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_BOT_LEFT)->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText())));
		objItem.setBotRight(ccp((float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_BOT_RIGHT)->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText()), 
								(float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_BOT_RIGHT)->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText())));
		objItem.setAnchor(ccp(	(float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_ANCHOR)->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText()), 
								(float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_ANCHOR)->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText())));
		objItem.setCenter(ccp(	(float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_CENTER)->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText()), 
								(float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_CENTER)->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText())));
		objItem.setPosition(ccp((float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_POS)->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText()), 
								(float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_POS)->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText())));
		ObjBoundaryContact objContact;
		objContact.setVisible(atoi(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_CONTACT)->FirstChildElement(KEY_BOUNDARY_VISIBLE)->GetText()));
		if(objContact.getVisible())
		{
			objContact.setAnchorBodyA(ccp(	(float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_CONTACT)->FirstChildElement(KEY_BOUNDARY_ANCHOR_BODY_A)->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText()), 
											(float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_CONTACT)->FirstChildElement(KEY_BOUNDARY_ANCHOR_BODY_A)->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText())));
			objContact.setAnchorBodyB(ccp(	(float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_CONTACT)->FirstChildElement(KEY_BOUNDARY_ANCHOR_BODY_B)->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText()), 
											(float)atof(pElement->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(strName.c_str())->FirstChildElement(KEY_BOUNDARY_CONTACT)->FirstChildElement(KEY_BOUNDARY_ANCHOR_BODY_B)->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText())));
		}
		objItem.setContact(objContact);
	}
	return objItem;
}

void ResourceManager::readObjBoundaryFile()
{
	do
	{
		tinyxml2::XMLElement* curNode = NULL;
		tinyxml2::XMLElement* rootNode = NULL;
		tinyxml2::XMLDocument* xmlDoc = new tinyxml2::XMLDocument();
		
#ifdef COCOS_V3
			ssize_t nSize;
#else
			unsigned long nSize;
#endif
			const char* pXmlBuffer = (const char*)CCFileUtils::sharedFileUtils()->getFileData((string("images/") + XML_BOUNDARY_FILE_NAME).c_str(), "rb", &nSize);
		//const char* pXmlBuffer = (const char*)data.getBuffer();
		if(NULL == pXmlBuffer)
		{
			CCLOG("can not read xml file");
			break;
		}
		xmlDoc->Parse(pXmlBuffer, nSize);
        delete[] pXmlBuffer;
		// get root node
		rootNode = xmlDoc->RootElement();
		
		if (NULL == rootNode)
		{
			CCLOG("read root node error");
			break;
		}
		// find the node
		curNode = rootNode->FirstChildElement();
		while (NULL != curNode)
		{
			ObjBoundary objBoundary;

//--------- get the Old boundary
			if(curNode->FirstChildElement(KEY_BOUNDARY_LIST_POS) != 0)
			{
				objBoundary.setTopLeft(ccp(	(float)atof(curNode->FirstChildElement(KEY_BOUNDARY_LIST_POS)->FirstChildElement(KEY_BOUNDARY_TOP_LEFT )->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText()), 
											(float)atof(curNode->FirstChildElement(KEY_BOUNDARY_LIST_POS)->FirstChildElement(KEY_BOUNDARY_TOP_LEFT )->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText())));
				objBoundary.setTopRight(ccp((float)atof(curNode->FirstChildElement(KEY_BOUNDARY_LIST_POS)->FirstChildElement(KEY_BOUNDARY_TOP_RIGHT)->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText()), 
											(float)atof(curNode->FirstChildElement(KEY_BOUNDARY_LIST_POS)->FirstChildElement(KEY_BOUNDARY_TOP_RIGHT)->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText())));
				objBoundary.setMidLeft(ccp( (float)atof(curNode->FirstChildElement(KEY_BOUNDARY_LIST_POS)->FirstChildElement(KEY_BOUNDARY_MID_LEFT )->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText()), 
											(float)atof(curNode->FirstChildElement(KEY_BOUNDARY_LIST_POS)->FirstChildElement(KEY_BOUNDARY_MID_LEFT )->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText())));
				objBoundary.setMidRight(ccp((float)atof(curNode->FirstChildElement(KEY_BOUNDARY_LIST_POS)->FirstChildElement(KEY_BOUNDARY_MID_RIGHT)->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText()), 
											(float)atof(curNode->FirstChildElement(KEY_BOUNDARY_LIST_POS)->FirstChildElement(KEY_BOUNDARY_MID_RIGHT)->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText())));
				objBoundary.setBotLeft(ccp( (float)atof(curNode->FirstChildElement(KEY_BOUNDARY_LIST_POS)->FirstChildElement(KEY_BOUNDARY_BOT_LEFT )->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText()), 
											(float)atof(curNode->FirstChildElement(KEY_BOUNDARY_LIST_POS)->FirstChildElement(KEY_BOUNDARY_BOT_LEFT )->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText())));
				objBoundary.setBotRight(ccp((float)atof(curNode->FirstChildElement(KEY_BOUNDARY_LIST_POS)->FirstChildElement(KEY_BOUNDARY_BOT_RIGHT)->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText()), 
											(float)atof(curNode->FirstChildElement(KEY_BOUNDARY_LIST_POS)->FirstChildElement(KEY_BOUNDARY_BOT_RIGHT)->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText())));
			}

// --------- get extension data
			// get RearWheel Info
			else if(curNode->FirstChildElement(KEY_BOUNDARY_LIST_COM) != 0)
			{
				ObjBoundaryComponent *pComponent = new ObjBoundaryComponent;
				// set wheels data
				ObjBoundaryWheel objFrontWheel;
				objFrontWheel.setPosition(ccp(	(float)atof(curNode->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(KEY_BOUNDARY_FRONT_WHEEL )->FirstChildElement(KEY_BOUNDARY_POS)->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText()), 
												(float)atof(curNode->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(KEY_BOUNDARY_FRONT_WHEEL )->FirstChildElement(KEY_BOUNDARY_POS)->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText())));
				objFrontWheel.setRadius(		(float)atof(curNode->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(KEY_BOUNDARY_FRONT_WHEEL )->FirstChildElement(KEY_BOUNDARY_RADIUS)->GetText()));
				pComponent->setFrontWheel(objFrontWheel);

				ObjBoundaryWheel objRearWheel;
				objRearWheel.setPosition(ccp(	(float)atof(curNode->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(KEY_BOUNDARY_REAR_WHEEL )->FirstChildElement(KEY_BOUNDARY_POS)->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText()), 
												(float)atof(curNode->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(KEY_BOUNDARY_REAR_WHEEL )->FirstChildElement(KEY_BOUNDARY_POS)->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText())));
				objRearWheel.setRadius(			(float)atof(curNode->FirstChildElement(KEY_BOUNDARY_LIST_COM)->FirstChildElement(KEY_BOUNDARY_REAR_WHEEL )->FirstChildElement(KEY_BOUNDARY_RADIUS)->GetText()));
				pComponent->setRearWheel(objRearWheel);

				// set body component 
				pComponent->setVehicleBody(getBoundaryItem(KEY_BOUNDARY_VEHICLE_BODY, curNode));
				pComponent->setPlayerHead(getBoundaryItem(KEY_BOUNDARY_PLAYER_HEAD, curNode));
				pComponent->setPlayerBody(getBoundaryItem(KEY_BOUNDARY_PLAYER_BODY, curNode));

				pComponent->setPlayerFrontArm(getBoundaryItem(KEY_BOUNDARY_PLAYER_FRONT_ARM, curNode));
				pComponent->setPlayerFrontHand(getBoundaryItem(KEY_BOUNDARY_PLAYER_FRONT_HAND, curNode));
				pComponent->setPlayerFrontThigh(getBoundaryItem(KEY_BOUNDARY_PLAYER_FRONT_THIGH, curNode));
				pComponent->setPlayerFrontLeg(getBoundaryItem(KEY_BOUNDARY_PLAYER_FRONT_LEG, curNode));

				pComponent->setPlayerBehindArm(getBoundaryItem(KEY_BOUNDARY_PLAYER_BEHIND_ARM, curNode));
				pComponent->setPlayerBehindHand(getBoundaryItem(KEY_BOUNDARY_PLAYER_BEHIND_HAND, curNode));
				pComponent->setPlayerBehindThigh(getBoundaryItem(KEY_BOUNDARY_PLAYER_BEHIND_THIGH, curNode));
				pComponent->setPlayerBehindLeg(getBoundaryItem(KEY_BOUNDARY_PLAYER_BEHIND_LEG, curNode));

				objBoundary.setComponent(pComponent);
			}

			if(curNode->FirstChildElement(KEY_BOUNDARY_IMG_NAME) != 0)
			{
				instance->m_mapObjBoundary[curNode->FirstChildElement(KEY_BOUNDARY_IMG_NAME)->GetText()] = objBoundary;
			}

			curNode = curNode->NextSiblingElement();
		}

		// check if have mapdata
		if(rootNode->FirstChildElement(KEY_BOUNDARY_MAP_DATA) != 0)
		{
			int  i = 0;
			tinyxml2::XMLElement* curNodeTemp = rootNode->FirstChildElement(KEY_BOUNDARY_MAP_DATA);

			// read arrMap
			{
				tinyxml2::XMLElement* curNodeTempItem = curNodeTemp->FirstChildElement(KEY_BOUNDARY_ARR_MAP)->FirstChildElement(KEY_BOUNDARY_ARR_ITEM);
				i = 0;
				while(NULL != curNodeTempItem)
				{
					CCPoint ccpTemp;
					ccpTemp.x = (float)atof(curNodeTempItem->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText());
					ccpTemp.y = (float)atof(curNodeTempItem->FirstChildElement(KEY_BOUNDARY_POS_Y)->GetText());
					ccpTemp.y += string(curNodeTempItem->FirstChildElement(KEY_BOUNDARY_MAP_TYPE)->GetText()).compare("s") == 0 ? MTS : MTB;
					ArrMap[i] = ccpTemp;
					i++;
					curNodeTempItem = curNodeTempItem->NextSiblingElement();
				}
			}

			// read arrCreateMetro
			{
				tinyxml2::XMLElement* curNodeTempItem = curNodeTemp->FirstChildElement(KEY_BOUNDARY_ARR_CREATE_METRO)->FirstChildElement(KEY_BOUNDARY_ARR_ITEM);
				i = 0;
				while(NULL != curNodeTempItem)
				{
					ArrCreateMetro[i] = (int)atoi(curNodeTempItem->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText());
					i++;
					curNodeTempItem = curNodeTempItem->NextSiblingElement();
				}
			}

			// read arrCreateCoin
			{
				tinyxml2::XMLElement* curNodeTempItem = curNodeTemp->FirstChildElement(KEY_BOUNDARY_ARR_CREATE_COIN)->FirstChildElement(KEY_BOUNDARY_ARR_ITEM);
				i = 0;
				while(NULL != curNodeTempItem)
				{
					ArrCreateCoin[i] = (int)atoi(curNodeTempItem->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText());
					i++;
					curNodeTempItem = curNodeTempItem->NextSiblingElement();
				}
			}

			// read arrCreateShape
			{
				tinyxml2::XMLElement* curNodeTempItem = curNodeTemp->FirstChildElement(KEY_BOUNDARY_ARR_CREATE_SHAPE)->FirstChildElement(KEY_BOUNDARY_ARR_ITEM);
				i = 0;
				while(NULL != curNodeTempItem)
				{
					ArrCreateShape[i] = (int)atoi(curNodeTempItem->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText());
					i++;
					curNodeTempItem = curNodeTempItem->NextSiblingElement();
				}
			}

			// read arrCoinValue
			{
				tinyxml2::XMLElement* curNodeTempItem = curNodeTemp->FirstChildElement(KEY_BOUNDARY_ARR_COIN_VALUE)->FirstChildElement(KEY_BOUNDARY_ARR_ITEM);
				i = 0;
				while(NULL != curNodeTempItem)
				{
					ArrCoinValue[i] = (int)atoi(curNodeTempItem->FirstChildElement(KEY_BOUNDARY_POS_X)->GetText());
					i++;
					curNodeTempItem = curNodeTempItem->NextSiblingElement();
				}
			}

			// read arrShapeData
			{
				tinyxml2::XMLElement* curNodeTempItem = curNodeTemp->FirstChildElement(KEY_BOUNDARY_ARR_SHAPE_DATA)->FirstChildElement(KEY_BOUNDARY_ARR_ITEM);
				i = 0;
				while(NULL != curNodeTempItem)
				{
					NTShapeData shapeDataTemp;

					shapeDataTemp.shapeType				= string(curNodeTempItem->FirstChildElement(KEY_BOUNDARY_SHAPE_TYPE)->GetText()).compare("b") == 0 ? NTShapeTypeBox : NTShapeTypeCircle;
					shapeDataTemp.fWidth				= (float)atof(curNodeTempItem->FirstChildElement(KEY_BOUNDARY_SHAPE_WIDTH)->GetText());
					shapeDataTemp.fHeight				= (float)atof(curNodeTempItem->FirstChildElement(KEY_BOUNDARY_SHAPE_HEIGHT)->GetText());
					shapeDataTemp.fDensityScale			= (float)atof(curNodeTempItem->FirstChildElement(KEY_BOUNDARY_SHAPE_DENSITY)->GetText());
					shapeDataTemp.fFrictionScale		= (float)atof(curNodeTempItem->FirstChildElement(KEY_BOUNDARY_SHAPE_FRICTION)->GetText());
					shapeDataTemp.fRestitutionScale		= (float)atof(curNodeTempItem->FirstChildElement(KEY_BOUNDARY_SHAPE_RESTITUTION)->GetText());

					ArrShapeData[i] = shapeDataTemp;
					i++;
					curNodeTempItem = curNodeTempItem->NextSiblingElement();
				}
			}

		}

		delete xmlDoc;
	}while(0);
}

CCLabelTTF* getLabelTTF(string text, int maxFontSize, const CCSize& dimensions, const CCPoint& position, CCTextAlignment alignment, bool fast)
{
	CCLabelTTF* aaa= CCLabelTTF::create(text.c_str(), "Arial", maxFontSize);
	aaa->setPosition(position);
	return aaa;
}

////////////////////////////////////////////////////////////////////////////////////////////
//                                         BOUNDARY                                       //
////////////////////////////////////////////////////////////////////////////////////////////

BoundaryObj* BoundaryObj::m_root = NULL;
bool NTCheat::getCheat(long code)
{
	if (code == 3212) //show Boudary
	{
		return true;
	}
	else if (code == 12343131) //no shit
	{
		return true;
	}
	else if (code == 9999) // Win, boss born
	{
		return false;
	}
	else if (code == 8888) //jump
	{
		return true;
	}
	return true;
}